/*
 * @Author: sjf 1758142861@qq.com
 * @Date: 2023-03-22 18:48:54
 * @LastEditors: sjf 1758142861@qq.com
 * @LastEditTime: 2023-04-03 18:50:39
 * @FilePath: /sjf/lwp/block_queue/forward_blockqueue.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/*
 * @Author: sjf 1758142861@qq.com
 * @Date: 2023-03-22 17:43:07
 * @LastEditors: sjf 1758142861@qq.com
 * @LastEditTime: 2023-03-22 18:48:53
 * @FilePath: /D_C_lib/block_queue/forward_blockqueue.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
//pthread_cond_wait函数的第二个参数，传入的必须是我们正在使用的互斥锁
//a.pthread_cond_wait:该函数调用的时候，会以原子性的方式，将锁释放，并将自己挂起
//b.pthread_cond_wait:该函数在被唤醒返回的时候，会自动重新获取自己传入的锁
#pragma once

#include <iostream>
#include <queue>
#include <pthread.h>
#include <unistd.h>

#define NUM 10

namespace Anwtie
{
    template <class T>
    class BlockQueue
    {
    public:
        BlockQueue(const int cap = NUM) : _cap(cap)
        {
            pthread_mutex_init(&_lock, nullptr);
            pthread_cond_init(&_full, nullptr);
            pthread_cond_init(&_empty, nullptr);
        }

        ~BlockQueue()
        {
            pthread_mutex_destroy(&_lock);
            pthread_cond_destroy(&_full);
            pthread_cond_destroy(&_empty);
        }

        void push(const T &data)//输入性参数 const &
        {
            pthread_mutex_lock(&_lock);
            while(queue_full())
            {
                pthread_cond_wait(&_full,&_lock);
            }
            _q.push(data);
            pthread_mutex_unlock(&_lock);
            pthread_cond_signal(&_empty);
        }

        void pop(T* data)//输出型参数 * // 输入性参数 &
        {
            pthread_mutex_lock(&_lock);
            while(queue_empty())
            {
                pthread_cond_wait(&_empty,&_lock);
            }
            *data = _q.front();
            _q.pop();
            pthread_cond_signal(&_full);
            pthread_mutex_unlock(&_lock);  
        }

    private:
        bool queue_full() { return _q.size() == _cap; }
        bool queue_empty() { return _q.empty(); }

    private:
        std::queue<T> _q;      // 队列
        int _cap;              // 队列最大所容纳数量
        pthread_mutex_t _lock; // 定义锁变量
        pthread_cond_t _full;  // 满定义变量
        pthread_cond_t _empty; // 空定义变量
    };
}